Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags. |
创建分级状态机
Description: 本教程教你如何嵌套不同的状态机,创建分级状态机。Tutorial Level: BEGINNER
Next Tutorial: 从SMACH状态机调用行为
创建一组状态
对于这个示例,我们创建一组状态,每一个包含指定的一组输出(outcomes),输出键(input keys)和输出键(output keys)。
1 # State Foo
2 class Foo(smach.State):
3 def __init__(self, outcomes=['outcome1', 'outcome2'])
4
5 def execute(self, userdata):
6 return 'outcome1'
7
8
9 # State Bar
10 class Bar(smach.State):
11 def __init__(self, outcomes=['outcome1'])
12
13 def execute(self, userdata):
14 return 'outcome4'
15
16
17 # State Bas
18 class Bas(smach.State):
19 def __init__(self, outcomes=['outcome3'])
20
21 def execute(self, userdata):
22 return 'outcome3'
创建分级状态机
我们创建一个顶级状态机,并开始向它添加状态。我们添加的一个状态是另一个状态机:
1 # Create the top level SMACH state machine
2 sm_top = smach.StateMachine(outcomes=['outcome5'])
3
4 # Open the container
5 with sm_top:
6
7 smach.StateMachine.add('BAS', Bas(),
8 transitions={'outcome3':'SUB'})
9
10 # Create the sub SMACH state machine
11 sm_sub = smach.StateMachine(outcomes=['outcome4'])
12
13 # Open the container
14 with sm_sub:
15
16 # Add states to the container
17 smach.StateMachine.add('FOO', Foo(),
18 transitions={'outcome1':'BAR',
19 'outcome2':'outcome4'})
20 smach.StateMachine.add('BAR', Bar(),
21 transitions={'outcome1':'FOO'})
22
23 smach.StateMachine.add('SUB', sm_sub,
24 transitions={'outcome4':'outcome5'})
结果是这样的。唯一需要注意的是,每个状态机也是一个正常状态。因此,你可以将状态机添加到另一个状态机,就像将状态添加到状态机一样。因此,处理用户数据与处理分级状态机没有什么不同:子状态机指定输入和输出键,当你将子状态机添加到顶层状态机时,它们会被重新映射。
示例
从executive_smach_tutorials包中可以找到可运行的完整示例.
1 #!/usr/bin/env python
2
3 import roslib; roslib.load_manifest('smach_tutorials')
4 import rospy
5 import smach
6 import smach_ros
7
8 # define state Foo
9 class Foo(smach.State):
10 def __init__(self):
11 smach.State.__init__(self, outcomes=['outcome1','outcome2'])
12 self.counter = 0
13
14 def execute(self, userdata):
15 rospy.loginfo('Executing state FOO')
16 if self.counter < 3:
17 self.counter += 1
18 return 'outcome1'
19 else:
20 return 'outcome2'
21
22
23 # define state Bar
24 class Bar(smach.State):
25 def __init__(self):
26 smach.State.__init__(self, outcomes=['outcome1'])
27
28 def execute(self, userdata):
29 rospy.loginfo('Executing state BAR')
30 return 'outcome1'
31
32
33
34 # define state Bas
35 class Bas(smach.State):
36 def __init__(self):
37 smach.State.__init__(self, outcomes=['outcome3'])
38
39 def execute(self, userdata):
40 rospy.loginfo('Executing state BAS')
41 return 'outcome3'
42
43
44
45
46 def main():
47 rospy.init_node('smach_example_state_machine')
48
49 # Create the top level SMACH state machine
50 sm_top = smach.StateMachine(outcomes=['outcome5'])
51
52 # Open the container
53 with sm_top:
54
55 smach.StateMachine.add('BAS', Bas(),
56 transitions={'outcome3':'SUB'})
57
58 # Create the sub SMACH state machine
59 sm_sub = smach.StateMachine(outcomes=['outcome4'])
60
61 # Open the container
62 with sm_sub:
63
64 # Add states to the container
65 smach.StateMachine.add('FOO', Foo(),
66 transitions={'outcome1':'BAR',
67 'outcome2':'outcome4'})
68 smach.StateMachine.add('BAR', Bar(),
69 transitions={'outcome1':'FOO'})
70
71 smach.StateMachine.add('SUB', sm_sub,
72 transitions={'outcome4':'outcome5'})
73
74 # Execute SMACH plan
75 outcome = sm_top.execute()
76
77
78
79 if __name__ == '__main__':
80 main()
运行示例:
$ roscd smach_tutorials $ ./examples/state_machine_nesting2.py